package com.hw.core.system.controller;


import com.hw.core.system.entity.*;
import com.hw.core.system.service.CourseReviewService;
import com.hw.core.system.service.CourseService;
import com.hw.core.system.service.NoteBookService;
import com.hw.core.system.service.UserService;
import com.hw.core.util.PasswordUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.util.*;

@Controller
public class PublicController {
    private static final Logger logger = LoggerFactory.getLogger( PublicController.class );
    @Autowired
    private CourseService courseService;
    @Autowired
    private NoteBookService noteBookService;
    @Autowired
    private CourseReviewService courseReviewService;


    @GetMapping("/")
    public String index(String name, Model model, Integer page, HttpSession session) throws Exception {
        if (session.getAttribute( "loginUser" ) == null) {
            Subject currentUser = SecurityUtils.getSubject();
            User principal = (User) currentUser.getPrincipal();
            session.setAttribute( "userid", principal.getNickname() + "[" + principal.getId() + "]" );
            session.setAttribute( "loginUser", principal );
        }
        Page<Course> coursePage = null;
        if (page == null) {
            if (null != name && !("".equals( name ))) {
                coursePage = courseService.findCourseFatherByNameLike( 1, 12, name );
            } else {
                coursePage = courseService.findCanShowCourseFather( 1, 12 );
            }

        } else {
            if (page < 1)
                throw new Exception( "参数错误" );
            if (null != name && !("".equals( name ))) {
                coursePage = courseService.findCourseFatherByNameLike( page, 12, name );
            } else {
                coursePage = courseService.findCanShowCourseFather( page, 12 );
            }
        }
        model.addAttribute( "name", name );
        model.addAttribute( "coursePage", coursePage );
        List<NoteBook> allNoteBook = noteBookService.findCanShowNoteBook();
        model.addAttribute( "noteBooks", allNoteBook );

        return "index";
    }


    @GetMapping("/showNoteBook/{id}")
    public String showNoteBook(@PathVariable Integer id, Model model) {
        if (id != null) {

            NoteBook noteBookById = noteBookService.findNoteBookById( id );

            model.addAttribute( "noteBook", noteBookById );
        }
        return "showNoteBook";
    }

    //访问父级课程进入
    @GetMapping("/show/{id}")
    public String show(@PathVariable Integer id, Model model) {
        if (id != null) {
            //当前显示的父课程
            Course showCourse = courseService.findCourseById( id );
            //该课程的子课程
            List<Course> courseByPId = courseService.findCourseByPId( showCourse.getId() );
            model.addAttribute( "course", courseByPId );
            //该父课程的同类父课程
            List<CourseType> courseTypes = showCourse.getCourseTypes();
            model.addAttribute( "typesCourse", courseService.findCourseByCourseTypesIn( courseTypes ) );

            model.addAttribute( "showCourse", showCourse );
        }
        return "show";
    }

    //访问子级课程进入
    @GetMapping("/show/{id}/{pId}")
    public String show(@PathVariable Integer id, @PathVariable Integer pId, Model model) {
        if (id != null) {
            Course showCourse = courseService.findCourseById( id );
            if (showCourse != null && (pId == null)) {
                List<Course> courseByPId = courseService.findCourseByPId( showCourse.getId() );
                model.addAttribute( "course", courseByPId );

            } else if (pId != null) {
                List<Course> courseByPId = courseService.findCourseByPId( pId );
                model.addAttribute( "course", courseByPId );
                Course father = courseService.findCourseById( pId );
                model.addAttribute( "father", father );
            }
            //父级才有课程类型
            Course father = courseService.findCourseById( pId );
            List<CourseType> courseTypes = father.getCourseTypes();
            model.addAttribute( "typesCourse", courseService.findCourseByCourseTypesIn( courseTypes ) );

            model.addAttribute( "showCourse", showCourse );
        }
        return "show";
    }

    //添加评论
    @PostMapping("addReview/{id}")
    @ResponseBody
    public String add(@PathVariable Integer id, String description) {
        Subject currentUser = SecurityUtils.getSubject();
        User loginUser = (User) currentUser.getPrincipal();
        if (id == null)
            return "参数错误";
        CourseReview courseReview = new CourseReview();
        courseReview.setDescription( description );
        courseReview.setCourse( new Course( id ) );
        courseReview.setUser( new User( loginUser.getId() ) );
        CourseReview add = courseReviewService.add( courseReview );
        if (add != null && add.getId() != null) {
            return "提交成功";
        } else {

            return "提交失败";
        }
    }


    @PostMapping("/login")
    public String login(@Valid User user, BindingResult bindingResult, RedirectAttributes redirectAttributes, HttpSession session) {
        if (bindingResult.hasErrors()) {
            redirectAttributes.addFlashAttribute( "message", bindingResult.getFieldError().getField() + ":" + bindingResult.getFieldError().getDefaultMessage() );
            return "redirect:/login";
        }

        String username = user.getName();
        UsernamePasswordToken token = new UsernamePasswordToken( user.getName(), user.getPassword() );
        token.setRememberMe( true );
        Subject currentUser = SecurityUtils.getSubject();
        try {
            logger.info( "对用户[" + username + "]进行登录验证..验证开始" );
            currentUser.login( token );
            logger.info( "对用户[" + username + "]进行登录验证..验证通过" );
        } catch (UnknownAccountException uae) {
            logger.info( "对用户[" + username + "]进行登录验证..验证未通过,未知账户" );
            redirectAttributes.addFlashAttribute( "message", "未知账户" );
        } catch (IncorrectCredentialsException ice) {
            logger.info( "对用户[" + username + "]进行登录验证..验证未通过,错误的凭证" );
            redirectAttributes.addFlashAttribute( "message", "密码不正确" );
        } catch (LockedAccountException lae) {
            logger.info( "对用户[" + username + "]进行登录验证..验证未通过,账户已锁定" );
            redirectAttributes.addFlashAttribute( "message", "账户已锁定" );
        } catch (ExcessiveAttemptsException eae) {
            logger.info( "对用户[" + username + "]进行登录验证..验证未通过,错误次数过多" );
            redirectAttributes.addFlashAttribute( "message", "用户名或密码错误次数过多" );
        } catch (AuthenticationException ae) {
            logger.info( "对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下" );
            ae.printStackTrace();
            redirectAttributes.addFlashAttribute( "message", "用户名或密码不正确" );
        }

        if (currentUser.isAuthenticated()) {
            logger.info( "用户[" + username + "]登录认证通过" );
            //聊天功能用户名
            User principal = (User) currentUser.getPrincipal();
            session.setAttribute( "userid", principal.getNickname() + "[" + principal.getId() + "]" );
            session.setAttribute( "loginUser", principal );
            return "redirect:/";
        } else {
            logger.info( "用户[" + username + "]登录失败" );
            token.clear();
            return "redirect:/login";
        }
    }


    @GetMapping("{name}")
    public String view(@PathVariable String name) {
        return name;
    }


}
